#pragma once

#include "ast.h"
#include "lexer.h"
#include "sema.h"
#include <vector>

class Parser
{
public:
    Parser(Lexer &lexer, Sema &sema) : lexer(lexer), sema(sema)
    {
        Advance();
    }
    std::shared_ptr<Program> ParseProgram();

private:
    std::shared_ptr<ASTNode> ParseStmt();
    std::shared_ptr<ASTNode> ParseDeclStmt();
    std::shared_ptr<ASTNode> ParseBlockStmt();
    std::shared_ptr<ASTNode> ParseExprStmt();
    std::shared_ptr<ASTNode> ParseIfStmt();
    std::shared_ptr<ASTNode> ParseForStmt();
    std::shared_ptr<ASTNode> ParseBreakStmt();
    std::shared_ptr<ASTNode> ParseContinueStmt();
    std::shared_ptr<ASTNode> ParseExpr();
    std::shared_ptr<ASTNode> ParseAssignExpr();
    std::shared_ptr<ASTNode> ParseEqualExpr();
    std::shared_ptr<ASTNode> ParseRelationalExpr();
    std::shared_ptr<ASTNode> ParseAddExpr();
    std::shared_ptr<ASTNode> ParseMultiExpr();
    std::shared_ptr<ASTNode> ParsePrimary();

    // 消耗 token 的函数
    // 检测 token 的类型
    bool Expect(TokenType tokenType);
    // 检测 token 的类型并消费
    bool Consume(TokenType tokenType);
    // 直接消耗当前的 token
    bool Advance();

    // 检查是否为类型名
    bool IsTypeName();

    DiagEngine &GetDiagEngine() const
    {
        return lexer.GetDiagEngine();
    }

private:
    Lexer &lexer;
    Sema &sema;
    Token token;
    std::vector<std::shared_ptr<ASTNode>> breakNodes;
    std::vector<std::shared_ptr<ASTNode>> continueNodes;
};